use strict;
use warnings;

sub compile_to_python {
	# get game data
	my $game_data = shift;

	my $world = "python_engine/world.py";

	# copy template engine to current directory
	mkdir("python_engine");
	copy("target/python/engine.py", "python_engine/engine.py");
	copy("target/python/object.py", "python_engine/object.py");
	copy("target/python/characteristic.py", "python_engine/characteristic.py");
	copy("target/python/transform.py", "python_engine/transform.py");
	copy("target/python/__init__.py", "python_engine/__init__.py");
	copy("target/python/templates/world.py.template", $world);

	my $init = "self.object = Object()\n\t\t";
	my $update = "";
	my $draw = "";
	foreach (@{$game_data->[0]}) {

		# currently the struture supports only one object
		#my $object = $game_data->[0][0];
		my $object = $_;

		my $name = $object->[0][1];
	
		# get shape of object and convert it from data in memory to python code
		my $shape = $object->[1];
		my $python_shape = "";
		my $i = 0;
		while ($i < @$shape) {
			#for (my $i = 0; $i < 18; $i++) {
			if ($i == 0 || $i % 3 == 0) {
				$python_shape = $python_shape . "(";
			}
			$python_shape = $python_shape . "$shape->[$i][1], ";
	
			if ( ($i-2) %3 == 0 ) {
				$python_shape = $python_shape . "), ";
			}
			$i++;
		}
	
		# get color of object and convert it to python code
		my $color = $object->[2];
		my $python_color = "(
			$color->[0][1],
			$color->[1][1],
			$color->[2][1]
			)";
		
		my $matrix = $object->[3];
		my $python_matrix = "(
			$matrix->[0][1], $matrix->[4][1], $matrix->[ 8][1], $matrix->[12][1],
			$matrix->[1][1], $matrix->[5][1], $matrix->[ 9][1], $matrix->[13][1],
			$matrix->[2][1], $matrix->[6][1], $matrix->[10][1], $matrix->[14][1],
			$matrix->[3][1], $matrix->[7][1], $matrix->[11][1], $matrix->[15][1])\n\t\t";
	
		# replace data from default world in python engine to the objects found earlier
		$init .= "self.$name = Object()\n\t\t";
		$init = $init . "self.$name.col = $python_color\n\t\t";
		$init = $init . "self.$name.pos = $python_shape\n\t\t";
		$init = $init . "self.$name.AddCharacteristic( Transform($python_matrix) )\n\t\t";
	
		my $actions = $object->[4];
		foreach (@$actions) {
			my $action = $_;
			my $action_name = $action->[0][1];
	
			if ($action_name eq "rotate") {
				my $action_data = $action->[1];
				#$update .= "self.$name.loc = rotate_matrix(self.$name.loc, $action_data->[0][1], '$action_data->[1][1]')";
			}
		}

		# draw
		$draw .= "self.$name.draw()\n\t\t";

	}

	# init
	replace_string($world, $world .".bk", "\@OBJECTS_INITIALIZATION@", $init);
	copy($world .".bk", $world);
	unlink($world .".bk");

	# update
	replace_string($world, $world .".bk", "\@OBJECTS_UPDATE@", $update);
	copy($world .".bk", $world);
	unlink($world .".bk");

	# draw
	replace_string($world, $world .".bk", "\@OBJECTS_DRAW@", $draw);
	copy($world .".bk", $world);
	unlink($world .".bk");
}

sub replace_string() {
	my $in_f = shift;
	my $out_f = shift;
	my $from = shift;
	my $to = shift;

	open(my $in, "<", $in_f) or die "$!";
	open(my $out, ">", $out_f) or die "$!";

	while (<$in>) {
		s/$from/$to/;
		print $out $_;
	}

	close $in;
	close $out;
}

sub copy() {
	my $in_f = shift;
	my $out_f = shift;

	open(my $in, "<", $in_f) or die "$!";
	open(my $out, ">", $out_f) or die "$!";

	while (<$in>) {
		print $out $_;
	}

	close $in;
	close $out;
}

return 1;
